package com.sergio.accounting.controller;

import com.sergio.accounting.dto.ApiResponse;
import com.sergio.accounting.dto.RecordDTO;
import com.sergio.accounting.dto.RecordResponseDTO;
import com.sergio.accounting.dto.StatisticsDTO;
import com.sergio.accounting.entity.Record;
import com.sergio.accounting.service.RecordService;
import com.sergio.accounting.util.UserContextUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.time.LocalDate;
import java.util.List;

/**
 * 记账记录控制器
 */
@Slf4j
@RestController
@RequestMapping("/records")
@RequiredArgsConstructor
@CrossOrigin
public class RecordController {

    private final RecordService recordService;

    /**
     * 添加记账记录
     */
    @PostMapping
    public ApiResponse<Record> addRecord(@RequestHeader("Authorization") String token,
                                       @RequestBody @Valid RecordDTO recordDTO) {
        try {
            Long userId = UserContextUtil.getCurrentUserId();
            if (userId == null) {
                return ApiResponse.error("用户未登录或token无效");
            }
            Record record = recordService.addRecord(userId, recordDTO);
            return ApiResponse.success("添加成功", record);
        } catch (Exception e) {
            log.error("添加记账记录失败: {}", e.getMessage());
            return ApiResponse.error(e.getMessage());
        }
    }

    /**
     * 更新记账记录
     */
    @PutMapping("/{id}")
    public ApiResponse<Record> updateRecord(@RequestHeader("Authorization") String token,
                                          @PathVariable Long id,
                                          @RequestBody @Valid RecordDTO recordDTO) {
        try {
            Long userId = UserContextUtil.getCurrentUserId();
            if (userId == null) {
                return ApiResponse.error("用户未登录或token无效");
            }
            Record record = recordService.updateRecord(userId, id, recordDTO);
            return ApiResponse.success("更新成功", record);
        } catch (Exception e) {
            log.error("更新记账记录失败: {}", e.getMessage());
            return ApiResponse.error(e.getMessage());
        }
    }

    /**
     * 删除记账记录
     */
    @DeleteMapping("/{id}")
    public ApiResponse<String> deleteRecord(@RequestHeader("Authorization") String token,
                                          @PathVariable Long id) {
        try {
            Long userId = UserContextUtil.getCurrentUserId();
            if (userId == null) {
                return ApiResponse.error("用户未登录或token无效");
            }
            boolean success = recordService.deleteRecord(userId, id);
            if (success) {
                return ApiResponse.success("删除成功");
            } else {
                return ApiResponse.error("删除失败");
            }
        } catch (Exception e) {
            log.error("删除记账记录失败: {}", e.getMessage());
            return ApiResponse.error(e.getMessage());
        }
    }

    /**
     * 根据ID查找记录
     */
    @GetMapping("/{id}")
    public ApiResponse<Record> getRecord(@PathVariable Long id) {
        try {
            Record record = recordService.findById(id);
            return ApiResponse.success(record);
        } catch (Exception e) {
            log.error("查找记账记录失败: {}", e.getMessage());
            return ApiResponse.error(e.getMessage());
        }
    }

    /**
     * 获取用户的所有记录
     */
    @GetMapping
    public ApiResponse<List<Record>> getUserRecords(@RequestHeader("Authorization") String token) {
        try {
            Long userId = UserContextUtil.getCurrentUserId();
            if (userId == null) {
                return ApiResponse.error("用户未登录或token无效");
            }
            List<Record> records = recordService.findByUserId(userId);
            return ApiResponse.success(records);
        } catch (Exception e) {
            log.error("获取用户记录失败: {}", e.getMessage());
            return ApiResponse.error(e.getMessage());
        }
    }

    /**
     * 根据类型获取用户记录
     */
    @GetMapping("/type/{recordType}")
    public ApiResponse<List<Record>> getRecordsByType(@RequestHeader("Authorization") String token,
                                                    @PathVariable String recordType) {
        try {
            Long userId = UserContextUtil.getCurrentUserId();
            if (userId == null) {
                return ApiResponse.error("用户未登录或token无效");
            }
            List<Record> records = recordService.findByUserIdAndType(userId, recordType);
            return ApiResponse.success(records);
        } catch (Exception e) {
            log.error("根据类型获取记录失败: {}", e.getMessage());
            return ApiResponse.error(e.getMessage());
        }
    }

    /**
     * 根据日期范围获取用户记录
     */
    @GetMapping("/date-range")
    public ApiResponse<List<RecordResponseDTO>> getRecordsByDateRange(@RequestHeader("Authorization") String token,
                                                         @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate startDate,
                                                         @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate endDate) {
        try {
            Long userId = UserContextUtil.getCurrentUserId();
            if (userId == null) {
                return ApiResponse.error("用户未登录或token无效");
            }
            List<RecordResponseDTO> records = recordService.findByUserIdAndDateRangeAsDTO(userId, startDate, endDate);
            return ApiResponse.success(records);
        } catch (Exception e) {
            log.error("根据日期范围获取记录失败: {}", e.getMessage());
            return ApiResponse.error(e.getMessage());
        }
    }

    /**
     * 根据类型和日期范围获取用户记录
     */
    @GetMapping("/type/{recordType}/date-range")
    public ApiResponse<List<Record>> getRecordsByTypeAndDateRange(@RequestHeader("Authorization") String token,
                                                               @PathVariable String recordType,
                                                               @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate startDate,
                                                               @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate endDate) {
        try {
            Long userId = UserContextUtil.getCurrentUserId();
            if (userId == null) {
                return ApiResponse.error("用户未登录或token无效");
            }
            List<Record> records = recordService.findByUserIdAndTypeAndDateRange(userId, recordType, startDate, endDate);
            return ApiResponse.success(records);
        } catch (Exception e) {
            log.error("根据类型和日期范围获取记录失败: {}", e.getMessage());
            return ApiResponse.error(e.getMessage());
        }
    }

    /**
     * 获取统计数据
     */
    @GetMapping("/statistics")
    public ApiResponse<StatisticsDTO> getStatistics(@RequestHeader("Authorization") String token,
                                                  @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate startDate,
                                                  @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate endDate) {
        try {
            Long userId = UserContextUtil.getCurrentUserId();
            if (userId == null) {
                return ApiResponse.error("用户未登录或token无效");
            }
            StatisticsDTO statistics = recordService.getStatistics(userId, startDate, endDate);
            return ApiResponse.success(statistics);
        } catch (Exception e) {
            log.error("获取统计数据失败: {}", e.getMessage());
            return ApiResponse.error(e.getMessage());
        }
    }

    /**
     * 获取概览数据
     */
    @GetMapping("/statistics/overview")
    public ApiResponse<StatisticsDTO.OverviewDTO> getOverview(@RequestHeader("Authorization") String token) {
        try {
            Long userId = UserContextUtil.getCurrentUserId();
            if (userId == null) {
                return ApiResponse.error("用户未登录或token无效");
            }
            StatisticsDTO.OverviewDTO overview = recordService.getOverview(userId);
            return ApiResponse.success(overview);
        } catch (Exception e) {
            log.error("获取概览数据失败: {}", e.getMessage());
            return ApiResponse.error(e.getMessage());
        }
    }

    /**
     * 获取趋势数据
     */
    @GetMapping("/statistics/trend")
    public ApiResponse<List<StatisticsDTO.TrendDTO>> getTrend(@RequestHeader("Authorization") String token,
                                                            @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate startDate,
                                                            @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate endDate) {
        try {
            Long userId = UserContextUtil.getCurrentUserId();
            if (userId == null) {
                return ApiResponse.error("用户未登录或token无效");
            }
            List<StatisticsDTO.TrendDTO> trend = recordService.getTrend(userId, startDate, endDate);
            return ApiResponse.success(trend);
        } catch (Exception e) {
            log.error("获取趋势数据失败: {}", e.getMessage());
            return ApiResponse.error(e.getMessage());
        }
    }

    /**
     * 获取分类统计
     */
    @GetMapping("/statistics/category")
    public ApiResponse<List<StatisticsDTO.CategoryStatsDTO>> getCategoryStats(@RequestHeader("Authorization") String token,
                                                                            @RequestParam String recordType,
                                                                            @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate startDate,
                                                                            @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate endDate) {
        try {
            Long userId = UserContextUtil.getCurrentUserId();
            if (userId == null) {
                return ApiResponse.error("用户未登录或token无效");
            }
            List<StatisticsDTO.CategoryStatsDTO> categoryStats = recordService.getCategoryStats(userId, recordType, startDate, endDate);
            return ApiResponse.success(categoryStats);
        } catch (Exception e) {
            log.error("获取分类统计失败: {}", e.getMessage());
            return ApiResponse.error(e.getMessage());
        }
    }

    /**
     * 获取排行榜
     */
    @GetMapping("/statistics/ranking")
    public ApiResponse<List<StatisticsDTO.RankingDTO>> getRanking(@RequestHeader("Authorization") String token,
                                                                @RequestParam String recordType,
                                                                @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate startDate,
                                                                @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate endDate) {
        try {
            Long userId = UserContextUtil.getCurrentUserId();
            if (userId == null) {
                return ApiResponse.error("用户未登录或token无效");
            }
            List<StatisticsDTO.RankingDTO> ranking = recordService.getRanking(userId, recordType, startDate, endDate);
            return ApiResponse.success(ranking);
        } catch (Exception e) {
            log.error("获取排行榜失败: {}", e.getMessage());
            return ApiResponse.error(e.getMessage());
        }
    }

    /**
     * 获取账户的历史记录
     */
    @GetMapping("/account/{accountId}")
    public ApiResponse<List<RecordResponseDTO>> getAccountRecords(@RequestHeader("Authorization") String token,
                                                                @PathVariable Long accountId) {
        try {
            Long userId = UserContextUtil.getCurrentUserId();
            if (userId == null) {
                return ApiResponse.error("用户未登录或token无效");
            }
            List<RecordResponseDTO> records = recordService.findByAccountId(accountId, userId);
            return ApiResponse.success(records);
        } catch (Exception e) {
            log.error("获取账户历史记录失败: {}", e.getMessage());
            return ApiResponse.error(e.getMessage());
        }
    }

    /**
     * 根据日期范围获取账户的历史记录
     */
    @GetMapping("/account/{accountId}/date-range")
    public ApiResponse<List<RecordResponseDTO>> getAccountRecordsByDateRange(@RequestHeader("Authorization") String token,
                                                                           @PathVariable Long accountId,
                                                                           @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate startDate,
                                                                           @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate endDate) {
        try {
            Long userId = UserContextUtil.getCurrentUserId();
            if (userId == null) {
                return ApiResponse.error("用户未登录或token无效");
            }
            List<RecordResponseDTO> records = recordService.findByAccountIdAndDateRange(accountId, userId, startDate, endDate);
            return ApiResponse.success(records);
        } catch (Exception e) {
            log.error("根据日期范围获取账户历史记录失败: {}", e.getMessage());
            return ApiResponse.error(e.getMessage());
        }
    }
}
